package cn.mrlong.base.utils

import android.content.Context
import android.content.SharedPreferences
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method

/**
 * 作者：BINGO
 * 时间：2021/03/29 11:20
 */
class SharedPreferencesUtils {
    private constructor()

    companion object {
        /**
         * 清除所有数据
         *
         * @param context
         */
        fun clear(context: Context, filename: String?) {
            val sp = context.getSharedPreferences(
                filename,
                Context.MODE_PRIVATE
            )
            val editor = sp.edit()
            editor.clear()
            SharedPreferencesCompat.apply(editor)
        }

        /**
         * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
         *
         * @author zhy
         */
        private object SharedPreferencesCompat {
            private val sApplyMethod = findApplyMethod()

            /**
             * 反射查找apply的方法
             *
             * @return
             */
            private fun findApplyMethod(): Method? {
                try {
                    val clz: Class<*> = SharedPreferences.Editor::class.java
                    return clz.getMethod("apply")
                } catch (e: NoSuchMethodException) {
                }
                return null
            }

            /**
             * 如果找到则使用apply执行，否则使用commit
             *
             * @param editor
             */
            fun apply(editor: SharedPreferences.Editor) {
                try {
                    if (sApplyMethod != null) {
                        sApplyMethod.invoke(editor)
                        return
                    }
                } catch (e: IllegalArgumentException) {
                } catch (e: IllegalAccessException) {
                } catch (e: InvocationTargetException) {
                }
                editor.commit()
            }
        }

        /**
         * 获取一个字符串
         *
         * @param context
         * @param filename
         * @param key
         * @param defValue
         * @return
         */
        fun getString(
            context: Context, filename: String?,
            key: String?, defValue: String?
        ): String? {
            val `object` = getObject(context, filename, key, defValue)
            return if (`object` != null) {
                `object` as String?
            } else defValue
        }

        /**
         * 从sp中获取一个int
         * @param context Context
         * @param filename String?
         * @param key String?
         * @param defValue Int
         * @return Int
         */
        fun getInt(
            context: Context, filename: String?, key: String?,
            defValue: Int
        ): Int {
            val `object` = getObject(context, filename, key, defValue)
            return if (`object` != null) {
                `object` as Int
            } else defValue
        }

        /**
         * 获取一个boolean类型的数据
         *
         * @param context
         * @param filename
         * @param key
         * @param defValue
         * @return
         */
        fun getBoolean(
            context: Context, filename: String?,
            key: String?, defValue: Boolean?
        ): Boolean? {
            val `object` = getObject(context, filename, key, defValue)
            return if (`object` != null) {
                `object` as Boolean?
            } else defValue
        }

        /**
         * 获取 Boolean, String 类型的数据
         *
         * @param context  接收一个上下文
         * @param filename 接收一个文件名
         * @param key      key
         * @param defValue value
         * @return
         */
        fun getObject(
            context: Context, filename: String?,
            key: String?, defValue: Any?
        ): Any? {
            return try {
                val sharedPreferences = context.getSharedPreferences(
                    filename, Context.MODE_PRIVATE
                )
                if (defValue is String || defValue == null) {
                    return sharedPreferences.getString(key, defValue as String?)
                }
                if (defValue is Boolean) {
                    return sharedPreferences.getBoolean(key, (defValue as Boolean?)!!)
                }
                if (defValue is Int) {
                    return sharedPreferences.getInt(key, (defValue as Int?)!!)
                }
                if (defValue is Float) {
                    return sharedPreferences.getFloat(key, (defValue as Float?)!!)
                }
                if (defValue is Long) {
                    sharedPreferences.getLong(key, (defValue as Long?)!!)
                } else null
            } catch (e: Exception) {
                null
            }
        }

        /**
         * 存储String ，Boolean类型的数据
         *
         * @param context  接收一个上下文
         * @param filename 文件名
         * @param key      key
         * @param defValue value
         */
        fun putObject(
            context: Context, filename: String?, key: String?,
            defValue: Any?
        ) {
            var defValue = defValue
            if (defValue == null) {
                defValue = ""
            }
            val sharedPreferences = context.getSharedPreferences(
                filename, Context.MODE_PRIVATE
            )
            if (defValue is String) {
                sharedPreferences.edit().putString(key, defValue as String?).commit()
            }
            if (defValue is Boolean) {
                sharedPreferences.edit().putBoolean(key, (defValue as Boolean?)!!)
                    .commit()
            }
            if (defValue is Int) {
                sharedPreferences.edit().putInt(key, (defValue as Int?)!!).commit()
            }
            if (defValue is Float) {
                sharedPreferences.edit().putFloat(key, (defValue as Float?)!!).commit()
            }
            if (defValue is Long) {
                sharedPreferences.edit().putLong(key, (defValue as Long?)!!).commit()
            }
        }

        /**
         * 从sp中获取到一个long
         * @param context Context
         * @param filename String?
         * @param key String?
         * @param defValue Long
         * @return Long
         */
        fun getLong(
            context: Context, filename: String?, key: String?,
            defValue: Long
        ): Long {
            return try {
                val sharedPreferences = context.getSharedPreferences(
                    filename, Context.MODE_PRIVATE
                )
                sharedPreferences.getLong(key, defValue)
            } catch (e: Exception) {
                defValue
            }
        }

        /**
         * 从sp中获取到一个boolean
         * @param context Context
         * @param filename String?
         * @param key String?
         * @param defValue Float
         * @return Float
         */
        fun getFloat(
            context: Context, filename: String?, key: String?,
            defValue: Float
        ): Float {
            return try {
                val sharedPreferences = context.getSharedPreferences(
                    filename, Context.MODE_PRIVATE
                )
                sharedPreferences.getFloat(key, defValue)
            } catch (e: Exception) {
                defValue
            }
        }
    }
}